{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Examples of Branching\n", "\n", "Whenever you issue one of the condition-code setting instructions, it sets the N, P, and Z registers depending on whether the number in that register is negative, positive, or zero.\n", "\n", "For example, if you use the ADD, AND, or NOT instruction and end up with 0000000000000000 in R0, then these registers would have the following:\n", "\n", "* N is 0\n", "* P is 0\n", "* Z is 1\n", "\n", "Exactly one of these will be 1 at any one time.\n", "\n", "The `BR` instruction is made up of:\n", "\n", "* opcode, 0000\n", "* n, z, and p bits to match\n", "* an offset to add to the PC\n", "\n", "The `BR` statement will look at any of the N, Z, or P registers, and if there is a match with any of the bits in the instruction, then it will set the PC to PC + offset.\n", "\n", "For example, this will always jump over the next instruction:\n", "\n", "```\n", "0000 111 000000001\n", "```\n", "\n", "This will always do nothing (eg, just go to next instruction), regardless of what ?s are because it won't match (n, z, and p are all 0s):\n", "\n", "```\n", "0000 000 ?????????\n", "```\n", "To demonstrate how branching works, we need to put something in a register, test it, and then branch to a new location.\n", "\n", "In this first example, we will:\n", "\n", "1. put 0 in R0\n", "2. branch to the next statement if that is zero\n", "3. add 1 to R0\n", "4. add 2 to r0\n", "5. HALT\n", "\n", "Here it is in machine language:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory dump:\n", "============================================================\n", " x3000: x5020\n", " x3001: x1021\n", " x3002: x1022\n", " x3003: xF025\n", " x3004: xF025\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3004\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", "0101 000 000 1 00000 ; R0 <- R0 and 0\n", "0000 111 000000000 ; BR NOOP\n", "0001 000 000 1 00001 ; R0 <- R0 + 1\n", "0001 000 000 1 00010 ; R0 <- R0 + 2\n", "1111 0000 00100101 ; HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 4\n", "Cycles: 27 (0.000013 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x0003 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3004 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory dump:\n", "============================================================\n", " x3000: x5020\n", " x3001: x0400\n", " x3002: x1021\n", " x3003: x1022\n", " x3004: xF025\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3005\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", "0101 000 000 1 00000 ; R0 <- R0 and 0\n", "0000 010 000000000 ; BR if zero to next statement\n", "0001 000 000 1 00001 ; R0 <- R0 + 1\n", "0001 000 000 1 00010 ; R0 <- R0 + 2\n", "1111 0000 00100101 ; HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 5\n", "Cycles: 33 (0.000017 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x0003 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3005 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Indeed, we see that R0 is 3, so it was created by executing the Add 1 and Add 2 instructions.\n", "\n", "In the next example, we will:\n", "\n", "1. put 0 in R0\n", "2. branch to the next, next statement if that is zero\n", "3. add 1 to R0\n", "4. add 2 to r0\n", "5. HALT" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory dump:\n", "============================================================\n", " x3000: x5020\n", " x3001: x0401\n", " x3002: x1021\n", " x3003: x1022\n", " x3004: xF025\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3005\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", "0101 000 000 1 00000 ; R0 <- R0 and 0\n", "0000 010 000000001 ; BR if zero to next, next statement\n", "0001 000 000 1 00001 ; R0 <- R0 + 1\n", "0001 000 000 1 00010 ; R0 <- R0 + 2\n", "1111 0000 00100101 ; HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 4\n", "Cycles: 27 (0.000013 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x0002 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3005 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And indeed we see that R0 is 2, so that it skipped over the R0 + 1 instruction.\n", "\n", "You can use the `BR` to do conditional code flow, like if, for, and while. Note that the offset can be negative." ] } ], "metadata": { "kernelspec": { "display_name": "Calysto LC3", "language": "asm", "name": "calysto_lc3" }, "language_info": { "file_extension": ".asm", "mimetype": "text/x-gas", "name": "gas" } }, "nbformat": 4, "nbformat_minor": 1 }